package com.eascs.banknet.boc.net.online;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.Socket;
import java.util.Date;
import java.util.List;

import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.eascs.app.log.Logger;
import com.eascs.app.log.LoggerFactory;
import com.eascs.banknet.boc.base.BOCUtil;
import com.eascs.banknet.boc.dao.DataListDao;
import com.eascs.banknet.boc.dao.LoanapplyDao;
import com.eascs.banknet.boc.net.BOCNetService;
import com.eascs.banknet.boc.vo.FtpFileTemplage;
import com.eascs.banknet.common.entity.DataListEntity;
import com.eascs.banknet.common.entity.LoanUserEntity;
import com.eascs.banknet.common.utils.CoreUtils;
import com.eascs.banknet.common.utils.DESPlus;
import com.eascs.banknet.common.utils.FTPUtils;
import com.eascs.banknet.common.vo.ServerInfo;
import com.eascs.banknet.constant.EAContant;
import com.eascs.banknet.constant.FileTypeConstants;
import com.eascs.common.util.StringUtil;

@Service("bocNetService")
public class BOCNetServiceImpl implements BOCNetService {
	private static final Logger logger = LoggerFactory.getLogger(BOCNetServiceImpl.class);
	private static final int TIMEOUT = 10 * 1000;
	@Autowired
	private BOCUtil bocUtil;
	@Autowired
	private DataListDao dataListDao;
	@Autowired
	private LoanapplyDao loanapplyDao;

	@SuppressWarnings("resource")
	@Override
	public String executeSocket(ServerInfo serverInfo, String type, String appno, String xml) throws Exception {
		String serverUrl = CoreUtils.formatString(serverInfo.getHref());
		int port = Integer.parseInt(CoreUtils.formatString(serverInfo.getPort()));
		// 加密xml
		String content = DESPlus.setBocencrypt(xml, EAContant.BOC_DECODEKEY);
		logger.info("开始建立连接, host:[{}], port:[{}]", serverUrl, port);
		Socket socket = new Socket(serverUrl, port);
		socket.setSoTimeout(TIMEOUT);
		// 向服务端写入数据,自动flusth
		PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
		out.println(content);

		// 读取服务端返回结果
		BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
		StringWriter writer = new StringWriter();
		writer = new StringWriter();
		char[] buf = new char[1024];
		int len;
		while ((len = in.read(buf)) != -1) {
			writer.write(buf, 0, len);
		}
		String result = writer.toString();
		if (StringUtil.isEmpty(result)) {
			return null;
		}
		// logger.info("服务端返回结果：{}", rs);
		// 解密xml
		String returnXml = DESPlus.getBocdecrypt(result, EAContant.BOC_DECODEKEY);
		socket.close();
		return returnXml;
	}

	@Override
	public boolean sendFtpAttachment(String appno, List<DataListEntity> fileList) throws Exception {
		ServerInfo eaFtpInfo = bocUtil.getEaFtpInfo();
		ServerInfo bocFtpInfo = bocUtil.getBocFtpInfo();
		if (null != fileList) {
			logger.info("开始向中行上传ftp文件，appno:[{}], fileCount：[{}]", appno, fileList.size());
			for (DataListEntity entity : fileList) {
				String attachMentName = entity.getUrlpath();
				if (StringUtil.isEmpty(attachMentName)) {
					logger.error("o2o_datalist.urlpath文件路径不存在");
					continue;
				}
				String remotePath = attachMentName.substring(0, attachMentName.lastIndexOf("/") + 1);
				String fileName = attachMentName.substring(attachMentName.lastIndexOf("/") + 1, attachMentName.length());
				// String fileType =
				// fileName.substring(fileName.lastIndexOf(".")+1);
				// FtpFileTemplage ftpFile =
				// bocUtil.getBocFtpFileTemplate(entity.getDatalistCode());
				String rootPath = StringUtil.hasText(bocUtil.getRootPath()) ? bocUtil.getRootPath() : "";
				String savePath = rootPath + appno; // 要保存的文件目录
				boolean result = copyFtpAttachment(eaFtpInfo, bocFtpInfo, remotePath, fileName, savePath, entity.getOriginalName(), appno);
				if (result) {
					entity.setIsFtp("Y");
					dataListDao.updateById(entity);
				}
			}
			logger.info("向中行上传ftp文件完成, appno:[{}]", appno);
			return true;
		}
		return false;
	}

	/**
	 * O2O系统中转FTP影像接口
	 * 
	 * @param eaFtpInfo
	 *            FTP服务器信息
	 * @param remotePath
	 *            FTP服务器上的相对路径
	 * @param fileName
	 *            FTP服务器上文件名
	 * @param newPath
	 *            服务器保存目录
	 * @param remark
	 *            要保存的文件名
	 * @return
	 */
	public boolean copyFtpAttachment(ServerInfo eaFtpInfo, ServerInfo bocFtpInfo, String remotePath, String fileName, String savePath, String saveName, String appno) throws Exception {
		boolean success = false;
		FTPClient ftp = new FTPClient();
		logger.info("开始向中行上传ftp文件,appno:[{}], remotePath:[{}], fileName:[{}], savePath[{}, saveName:[{}]]", appno, remotePath, fileName, savePath, saveName);
		int reply;
		ftp.connect(eaFtpInfo.getHref(), eaFtpInfo.getPort());
		// 如果采用默认端口，可以使用ftp.connect(url)的方式直接连接FTP服务器
		ftp.login(eaFtpInfo.getUsername(), eaFtpInfo.getPassword());// 登录
		reply = ftp.getReplyCode();
		if (!FTPReply.isPositiveCompletion(reply)) {
			ftp.disconnect();
			return success;
		}
		ftp.setBufferSize(2048 * 2);
		ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
		ByteArrayOutputStream fos = new ByteArrayOutputStream();
		ftp.retrieveFile(remotePath + fileName, fos);
		ByteArrayInputStream in = new ByteArrayInputStream(fos.toByteArray());
		if (null != in) {
			// 中转FTP影像接口地址
			FTPUtils.uploadFile(CoreUtils.formatString(bocFtpInfo.getHref()), CoreUtils.parseLong(CoreUtils.formatString(bocFtpInfo.getPort())).intValue(), CoreUtils.formatString(bocFtpInfo.getUsername()),
					CoreUtils.formatString(bocFtpInfo.getPassword()), savePath, saveName, in);
			fos.flush();
			fos.close();
			in.close();
			// 记录附件表
		}
		ftp.logout();
		if (ftp.isConnected()) {
			ftp.disconnect();
		}
		success = true;
		logger.info("向中行上传ftp文件成功,appno:[{}], savePath[{}, saveName:[{}]]", appno, savePath, saveName);
		return success;
	}

	@Override
	public boolean getFtpAttachment(FtpFileTemplage ftpFile, String appno, String loanapplyNo, String bankOsn) throws Exception {
		boolean result = false;
		ServerInfo bocFtpInfo = bocUtil.getBocFtpInfo();
		ServerInfo eaFtpInfo = bocUtil.getEaFtpInfo();
		String fileType = ftpFile.getFileType();
		String fromPath = ftpFile.getLoadPath() + appno;
		String yearmonth = CoreUtils.getFourBitYearMonth(new Date());
		String datepath = yearmonth.substring(0, 2) + "/" + yearmonth.substring(2, 4) + "/";
		if (FileTypeConstants.DALIST_TYPE_REFUNDCONTRACTBAK.equals(fileType)) {
			if (StringUtil.isEmpty(bankOsn))
				return true;
			fromPath = ftpFile.getLoadPath() + appno + "/" + bankOsn;
		}
		String savePath = ftpFile.getFileType() + "/" + datepath;

		FTPClient ftp = new FTPClient();
		// String appno = fromPath.substring(fromPath.lastIndexOf("/")+1);
		int reply;
		ftp.connect(bocFtpInfo.getHref(), bocFtpInfo.getPort());
		// 如果采用默认端口，可以使用ftp.connect(url)的方式直接连接FTP服务器
		ftp.login(bocFtpInfo.getUsername(), bocFtpInfo.getPassword());
		reply = ftp.getReplyCode();
		if (!FTPReply.isPositiveCompletion(reply)) {
			ftp.disconnect();
			return result;
		}
		ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
		// ftp.setControlEncoding("GBK");
		// 转移到FTP服务器目录
		if (ftp.changeWorkingDirectory(fromPath)) {
			FTPFile[] fs = ftp.listFiles();
			if (null != fs) {
				for (FTPFile ff : fs) {
					if (StringUtil.hasText(ff.getName())) {
						ByteArrayOutputStream fos = new ByteArrayOutputStream();
						String randomstr = Long.toString(System.currentTimeMillis()) + CoreUtils.getRandomString(2);
						String filename = new String(ff.getName().getBytes("ISO-8859-1"), "GBK");
						String extendname = filename.substring(filename.lastIndexOf(".") + 1, filename.length()).toLowerCase();
						String newFileName = randomstr + "." + extendname;
						ftp.retrieveFile(ff.getName(), fos);
						ByteArrayInputStream input = new ByteArrayInputStream(fos.toByteArray());
						if (null != input) {
							// 保存文件信息
							String attachmentname = savePath + randomstr + "." + extendname;
							String originalname = new String(ff.getName().getBytes("ISO-8859-1"), "GBK");
							DataListEntity dataListEntity = new DataListEntity();
							dataListEntity.setLoanapplyNo(loanapplyNo);
							dataListEntity.setOriginalName(originalname);
							dataListEntity.setExtendNmae(extendname);
							dataListEntity.setUrlpath(attachmentname);
							dataListEntity.setCreatDate(new Date());
							dataListEntity.setDatalistCode(ftpFile.getFileType());
							dataListEntity.setDatalistName(ftpFile.getFileDesc());
							dataListEntity.setCreatOr("system");
							dataListEntity.setUpdateTime(new Date());
							dataListEntity.setIsFtp("N");
							dataListEntity.setIsDelete("N");
							LoanUserEntity loanUserEntity = loanapplyDao.getLoanUserByAppno(appno);
							dataListEntity.setSponsorId(loanUserEntity.getId());
							if (FileTypeConstants.DALIST_TYPE_REFUNDCONTRACTBAK.equals(fileType)) {
								if ("Contract.pdf".equals(originalname)) {
									dataListEntity.setOriginalName("借款合同.pdf");
									dataListEntity.setDatalistName("借款合同(中行电子合同)");
								}
								if ("ReceLoan.pdf".equals(originalname)) {
									dataListEntity.setOriginalName("借款借据.pdf");
									dataListEntity.setDatalistName("借款借据(中行电子合同)");
								}
							}
							logger.info("下载文件，appno:[{}], savePath:[{}], filename:[{}], fileType:[{}]", appno, savePath, newFileName, fileType);
							boolean hasUpload = FTPUtils.uploadFile(CoreUtils.formatString(eaFtpInfo.getHref()), eaFtpInfo.getPort(), CoreUtils.formatString(eaFtpInfo.getUsername()),
									CoreUtils.formatString(eaFtpInfo.getPassword()), savePath, randomstr + "." + extendname, input);
							if (hasUpload)
								dataListDao.insert(dataListEntity);
							logger.info("文件下载完成，appno:[{}],loanapplyNo:[{}], datalistCode:[{}], originalname:[{}]", appno, loanapplyNo, dataListEntity.getDatalistCode(), originalname);
							result = true;
						}
					}
				}
			}
		}
		ftp.logout();
		result = true;
		if (ftp.isConnected()) {
			ftp.disconnect();
		}
		return result;
	}

	@Override
	public ByteArrayInputStream readFtpFile(ServerInfo serverInfo, String remotePath, String fileName) {
		return FTPUtils.FtpReadTxtFile(serverInfo.getHref(), serverInfo.getPort(), serverInfo.getUsername(), serverInfo.getPassword(), remotePath, fileName);
	}
}